// websocketserverimpl.h
#pragma once
#include <memory>
#include <string>
#include <set>
#include <mutex>
#include <deque>
#include <functional>
#include <unordered_map>
#include "websocketserver/websocketserver.h"
#include "../core/callable.hpp"

namespace hhfox
{
    using server = websocketpp::server<websocketpp::config::asio>;
    using message_ptr = server::message_ptr;

    class IWebSocketHandler;

    class WebSocketServerImpl: public Callable<WebSocketServerImpl>
    {
    public:
        WebSocketServerImpl(const char *host, int port);

        ~WebSocketServerImpl();

        void setLoggerCallback(Logger&& logger);

        void sendRawMessage(websocketpp::connection_hdl hdl,void *buff, size_t len,websocketpp::frame::opcode::value op);

        void sendRawMessage(websocketpp::connection_hdl hdl,const std::string& msg);

        void quit();

        void run();

        void registerHandler(const std::string &uri, std::shared_ptr<IWebSocketHandler> handler);

        connection_ptr get_con_from_hdl(connection_hdl hdl);

    public:
        void on_open(server *s, websocketpp::connection_hdl hdl);
        void on_close(server *s, websocketpp::connection_hdl hdl);
        void on_http(server *s, websocketpp::connection_hdl hdl);
        void on_message(server *s, websocketpp::connection_hdl hdl, message_ptr msg);

    private:
        std::string host_;
        int port_;
        server svr_;
        std::unordered_map<std::string, std::shared_ptr<IWebSocketHandler>> handlers_;
    };
}